/*******************************************************************************
 * Copyright (c) 2007, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - Initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.server.preview.internal;

import java.io.File;

import org.eclipse.wst.server.preview.openejb.jetty.loader.JettyListener;
import org.eclipse.wst.server.preview.openejb.jetty.loader.ServerHolder;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.handler.HandlerList;
import org.mortbay.jetty.webapp.WebAppContext;

public class PreviewStarter {
	protected String configPath;
	protected Server server;

	public PreviewStarter(String configPath) {
		this.configPath = configPath;
	}

	public static void main(String[] args) {
		PreviewStarter app = new PreviewStarter(args[0]);
		app.run();
	}

	protected void run() {
		try {
			System.setProperty("org.mortbay.log.class", "org.eclipse.wst.server.preview.internal.WTPLogger");
			ServerConfig config = new ServerConfig(configPath);
			System.out.println("Starting preview server on port " + config.getPort());
			System.out.println();
			Module[] m = config.getModules();
			int size = m.length;
			if (size > 0) {
				System.out.println("Modules:");
				for (Module mm : m)
					System.out.println("  " + mm.getName() + " (" + mm.getContext() + ")");
				System.out.println();
			}
			
			server = new Server(config.getPort());
			server.setStopAtShutdown(true);
			
			WTPErrorHandler errorHandler = new WTPErrorHandler();
			
			HandlerList handlers = new HandlerList();
			
			System.getProperties().put("java.naming.factory.initial", "org.mortbay.naming.InitialContextFactory");
			
			//Added on OpenEJB integration: Adding OpenEJB module
			Module openejb = new Module("openejb" , false , "/openejb" , System.getProperty("openejb.war"));
			WebAppContext openEJBContext = addWebModule(openejb, handlers , errorHandler );
			System.setProperty("openejb.webapp" , openEJBContext.getTempDirectory() + "/webapp" );
			System.setProperty("openejb.jndiname.format" , "{ejbName}/{interfaceClass}" );
						
			
			//Added on OpenEJB integration: Adding OpenEJBMonitor module
			//This webapp is used to monitor the OpenEJB container status.
			Module openejbMonitor = new Module("openejbMonitor" , false , "/openejbmonitor" , System.getProperty("openejb-monitor.war"));
			addWebModule(openejbMonitor, handlers , errorHandler );
			
			for (Module module : m) {
				if (module.isStaticWeb()) {
					ContextResourceHandler resourceHandler = new ContextResourceHandler();
					resourceHandler.setResourceBase(module.getPath());
					resourceHandler.setContext(module.getContext());
					handlers.addHandler(resourceHandler);
				} else {
					addWebModule( module, handlers, errorHandler);
				}
			}
			
			Module[] modules = new Module[ m.length +1 ];
			System.arraycopy( m , 0 , modules , 0, m.length );
			modules[ modules.length-1 ] = openejb;
			
			handlers.addHandler(new WTPDefaultHandler(config.getPort(), m ));
			
			server.setHandler(handlers);
			
			try {
				//Added on OpenEJB integration
				ServerHolder.setServer( server );
				server.addLifeCycleListener( new JettyListener( ) );
				
				server.start();
			} catch (Exception e) {
				e.printStackTrace();
			}
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	private WebAppContext addWebModule( Module module , HandlerList handlers, WTPErrorHandler errorHandler){
		WebAppContext webapp = new WebAppContext();
		
		webapp.setContextPath( module.getContext() );
		webapp.setWar( module.getPath() );
		webapp.setDefaultsDescriptor("./webdefault.xml");
		webapp.setErrorHandler(errorHandler);
		
		//Added on OpenEJB integration
		webapp.setConfigurationClasses(new String[] {
		        // These are default, but will be overwritten if we don't specify them
		        "org.mortbay.jetty.webapp.WebInfConfiguration",   
		        "org.mortbay.jetty.annotations.Configuration",
		        "org.mortbay.jetty.webapp.JettyWebXmlConfiguration",
		        "org.mortbay.jetty.webapp.TagLibConfiguration",
		        "org.mortbay.jetty.plus.webapp.EnvConfiguration",
		    });
		
		webapp.setParentLoaderPriority( true );
		
		handlers.addHandler(webapp);
		return webapp;
	}
	
	public void stop() {
		try {
			System.out.println("Stop!");
			server.stop();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * deleteDirectory is a convenience method to recursively delete a directory
	 * @param directory - the directory to delete.
	 * @return was the delete successful
	 */
	protected static boolean deleteDirectory(File directory) {
		if (directory.exists() && directory.isDirectory()) {
			File[] files = directory.listFiles();
			for (File file : files) {
				if (file.isDirectory()) {
					deleteDirectory(file);
				} else {
					file.delete();
				}
			}
		}
		return directory.delete();
	}
	
}